<?php
/**	
*	FILENAME: 		/libraries/ldap.php
*	DESCRIPTION:	This library contains functions used to interact with Villanova University's LDAP server.
*	AUTHOR:			Casey Burkhardt
*	VERSION:		1.0.0
*	LAST MODIFIED:	12/31/2009
**/

global $LDAP_HOSTNAME;
$LDAP_HOSTNAME = "ldap.villanova.edu";

/**	
*	DESCRIPTION:	Checks if the provided LDAP username and password is valid for a Villanova student, faculty member, or staff member
**/
function authenticateLDAPUser($username, $password) {
	global $LDAP_HOSTNAME;
	
	// First construct all of the RDN values for each bind attempt.
	// Students
	$rdn1 = "uid=" . $username . ", ou=" . strtoupper(substr($username, 0, 1)) . ", ou=Students, o=villanova.edu";
	$rdn2 = "uid=" . $username . ", ou=People, o=villanova.edu";
	// Faculty
	$rdn3 = "uid=" . $username . ", ou=Faculty, ou=Employees, o=villanova.edu";
	// Staff
	$rdn4 = "uid=" . $username . ", ou=Staff, ou=Employees, o=villanova.edu";
	
	$ldapConnection = ldap_connect($LDAP_HOSTNAME);
	if ($ldapConnection) {
		$bind1 = @ldap_bind($ldapConnection, $rdn1, $password);
		$bind2 = @ldap_bind($ldapConnection, $rdn2, $password);
		$bind3 = @ldap_bind($ldapConnection, $rdn3, $password);
		$bind4 = @ldap_bind($ldapConnection, $rdn4, $password);
		
		// Authenticate if any of the bind attempts worked.
		if ($bind1 || $bind2 || $bind3 || $bind4) {
			return TRUE;
		} else {
			return FALSE;
		}
		ldap_close($ldapConnection);
	} else {
		return FALSE;
	}
}

/**	
*	DESCRIPTION:	Checks to see if an LDAP record exists on the Villanova LDAP server.
**/
function checkLDAPRecord($leadNodes, $target_node) {
	global $LDAP_HOSTNAME;
	
	// Connect and Bind anonymously to the Villanova LDAP server.
	$ldapConnection = ldap_connect($LDAP_HOSTNAME);
	if ($ldapConnection) {
		$bind = @ldap_bind($ldapConnection);
		$result = @ldap_search($ldapConnection, $leadNodes, $target_node);
		if (ldap_count_entries($ldapConnection, $result) > 0) {
			return TRUE;
		} else {
			return FALSE;
		}
	} else {
		return FALSE;
	}
}

/**	
*	DESCRIPTION:	Determines the record type based on a given UID value by checking against the structure of the LDAP server tree.
**/
function ldap_record_type($userID) {
	global $LDAP_HOSTNAME;
	
	// Connect and Bind anonymously to the Villanova LDAP server.
	$ldapConnection = ldap_connect($LDAP_HOSTNAME);
	if ($ldapConnection) {
		$bind = @ldap_bind($ldapConnection);
		if (ldap_count_entries($ldapConnection, @ldap_search($ldapConnection, "ou=" . strtoupper(substr($userID, 0, 1)) . ", ou=Students, o=villanova.edu", "uid=" . $userID)) > 0) {
			return "Student";
		} elseif (ldap_count_entries($ldapConnection, @ldap_search($ldapConnection, "ou=People, o=villanova.edu", "uid=" . $userID)) > 0) {
			return "Student";
		} elseif (ldap_count_entries($ldapConnection, @ldap_search($ldapConnection, "ou=Faculty, ou=Employees, o=villanova.edu", "uid=" . $userID)) > 0) {
			return "Faculty";
		} elseif (ldap_count_entries($ldapConnection, @ldap_search($ldapConnection, "ou=Staff, ou=Employees, o=villanova.edu", "uid=" . $userID)) > 0) {
			return "Staff";
		} else {
			return FALSE;
		}
	} else {
		return FALSE;
	}
}

/**	
*	DESCRIPTION:	Returns all fields of an LDAP record given the record's lead nodes and the user ID.
**/
function ldap_record($leadNodes, $userID) {
	global $LDAP_HOSTNAME;
	
	// Connect and Bind anonymously to the Villanova LDAP server.
	$ldapConnection = ldap_connect($LDAP_HOSTNAME);
	if ($ldapConnection) {
		$bind = @ldap_bind($ldapConnection);
		if (ldap_count_entries($ldapConnection, @ldap_search($ldapConnection, $leadNodes, "uid=" . $userID)) > 0) {
			$result = ldap_search($ldapConnection, $leadNodes, "uid=" . $userID);
		    $record = ldap_get_entries($ldapConnection, $result);
			return $record;
		} else {
			return FALSE;
		}
	} else {
		return FALSE;
	}
}

/**	
*	DESCRIPTION:	Returns several LDAP record fields for each LDAP record found given a search string.
**/
function ldapSearch($searchQuery) {
	global $LDAP_HOSTNAME;
	
	$ldapConnection = ldap_connect($LDAP_HOSTNAME);
	if ($ldapConnection) {
		// Search the four root dn's in parallel.
		$dnValues[] = "ou=People, o=villanova.edu";
		$dnValues[] = "ou=Students, o=villanova.edu";
		$dnValues[] = "ou=Faculty, ou=Employees, o=villanova.edu";
		$dnValues[] = "ou=Staff, ou=Employees, o=villanova.edu";
		
		foreach ($dnValues as $i) {
			// Every dn needs an associated connection resource.
			$connections[] = $ldapConnection;
		}
		
		// We'll search for any username, last name, first name, or full name that contains the search query.
		$searchString = "(|(uid=$searchQuery*)(sn=$searchQuery*)(givenname=$searchQuery*)(cn=$searchQuery*))";

		// Return only the userID, full name, and organizaitonal unit of the resulting entries.
		$resultLimiters = array("uid", "cn", "ou");
		$searchResults = ldap_search($connections, $dnValues, $searchString, $resultLimiters);

		$results = array();
		$resultCount = 0;

		// Iterate over each search result from each dn, and aggregate the results.
		foreach ($searchResults as $value) {
			if(ldap_count_entries($ldapConnection, $value) > 0) {
				$info = ldap_get_entries($ldapConnection, $value);
				$count = $count + $info["count"];
				$results = array_merge($results, $info);
			}
		}
		
		// Update the final result count and return results.
		$results["count"] = $count;
		return $results;
	} else {
		return FALSE;
	}	
}
?>